﻿#region File and License Information
/*
<File>
	<License>
		Copyright © 2009 - 2017, Daniel Vaughan. All rights reserved.
		This file is part of Calcium (http://calciumsdk.net), 
		which is released under the MIT License.
		See file /Documentation/License.txt for details.
	</License>
	<CreationDate>2009-04-11 19:51:16Z</CreationDate>
</File>
*/
#endregion

using System;
using System.Collections;
using System.Collections.Generic;
using System.ServiceModel;
using System.Threading.Tasks;

using Outcoder.Services.DialogService;
using Outcoder.Services.Implementation;

namespace Outcoder.Services
{
	/// <summary>
	/// This service allows feedback to be gathered from a user.
	/// In the implementation this will generally be done using a modal dialog box.
	/// </summary>
	[ServiceContract(Namespace = OrganizationalConstants.ServiceContractNamespace)]
	public interface IDialogService
	{
		/// <summary>
		/// Shows a message to a user that must be dismissed before continuing.
		/// </summary>
		/// <param name="message">The message to display.</param>
		/// <param name="caption">The caption to display on the dialog.</param>
		/// <param name="importanceThreshold">The minimum filter level 
		/// that a user must have in order to receive the message.</param>
		[OperationContract(IsOneWay = true, Name = "ShowDialogWithCaption")]
		Task ShowMessageAsync(
			string message,
			string caption = null,
			DialogImportance importanceThreshold = DialogImportance.High,
			object expandableDetails = null);

		/// <summary>
		/// Shows a warning message to a user that must be dismissed before continuing.
		/// </summary>
		/// <param name="message">The message to display.</param>
		/// <param name="caption">The caption to display on the dialog.</param>
		[OperationContract(IsOneWay = true, Name = "ShowWarningWithCaption")]
		Task ShowWarningAsync(string message, string caption = null, object expandableDetails = null);

		/// <summary>
		/// Shows an error message to a user that must be dismissed before continuing.
		/// </summary>
		/// <param name="message">The message to display.</param>
		/// <param name="caption">The caption to display on the dialog.</param>
		[OperationContract(IsOneWay = true, Name = "ShowErrorWithCaption")]
		Task ShowErrorAsync(string message, string caption = null, object expandableDetails = null);

		/// <summary>
		/// Presents a dialog to the user with the specified buttons.
		/// </summary>
		/// <param name="body">The body text.</param>
		/// <param name="caption">The caption to display on the dialog.</param>
		/// <param name="cancelButtonIndex">If the user escapes out of the dialog, this index is returned.</param>
		/// <returns><code>true</code> if the user selected 'yes'; 
		/// <code>false</code> otherwise.</returns>
		[OperationContract(Name = "AskYesNoQuestionWithCaption")]
		Task<int?> ShowDialogAsync(object body, IEnumerable<object> buttons,
									string caption = null,
									int defaultAcceptButtonIndex = -1,
									object expandableDetails = null,
									DialogController dialogController = null);

		/// <summary>
		/// Presents a dialog to the user with the specified buttons.
		/// </summary>
		/// <param name="body">The body text.</param>
		/// <param name="caption">The caption to display on the dialog.</param>
		/// <param name="cancelButtonIndex">If the user escapes out of the dialog, this index is returned.</param>
		/// <returns><code>true</code> if the user selected 'yes'; 
		/// <code>false</code> otherwise.</returns>
		[OperationContract(Name = "ShowDialogAsyncWithPredefinedButtons")]
		Task<DialogResult> ShowDialogAsync(
			object content,
			string caption,
			DialogButton dialogButton,
			DialogImage dialogImage = DialogImage.None,
			DialogImportance importanceThreshold = DialogImportance.High,
			object details = null,
			DialogController dialogController = null);

		Task<QuestionResponse<TResponse>> AskQuestionAsync<TResponse>(
			IQuestion<TResponse> question);

		Task<bool> AskOkCancelQuestionAsync(
			string question, string caption = null, object expandableDetails = null);

		Task<bool> AskYesNoQuestionAsync(
			string question, string caption = null, object expandableDetails = null);

		Task<YesNoCancelQuestionResult> AskYesNoCancelQuestionAsync(
			string question, string caption = null, object expandableDetails = null);

#if WINDOWS_PHONE || WINDOWS_UWP || __ANDROID__
		Task<object> ShowToastAsync(ToastParameters toastParameters);

		Task<object> ShowToastAsync(string caption, string body = null);

		bool DialogOpen { get; }
#endif

#if __ANDROID__ || MONODROID
		Android.Content.Context Context { set; }

		int DialogStyle { get; }
#endif
	}

	public class ToastParameters
	{
		public ToastParameters()
		{
			VerticalOrientation = ToastVerticalOrientation.Top;
		}

		public object Caption { get; set; }
		public object Body { get; set; }
		public ToastTextOrientation? TextOrientation { get; set; }
		public Uri ImageUri { get; set; }
		public int? MillisecondsUntilHidden { get; set; }
		public double? ImageWidth { get; set; }
		public double? ImageHeight { get; set; }

		public ToastVerticalOrientation? VerticalOrientation { get; set; }

		public ToastAnimationType? AnimationType { get; set; }
	}

	public enum ToastVerticalOrientation
	{
		Top,
		Center,
		Bottom,
		Stretch
	}

	public enum ToastAnimationType
	{
		Slide,
		SlideHorizontal,
		Swivel,
		SwivelHorizontal,
		Fade
	}

	public enum ToastTextOrientation
	{
		Vertical,
		Horizontal
	}

	public class DialogController
	{
		public event EventHandler CloseRequested;

		public virtual void Close(EventArgs e)
		{
			var temp = CloseRequested;
			if (temp != null)
			{
				temp(this, e);
			}
		}

		public bool Cancellable { get; set; }

		public DialogStyles? DialogStyles { get; set; }

//#if MONODROID
//		public Android.Graphics.Drawables.Drawable BackgroundImage { get; set; }
//#endif
	}

	[Flags]
	public enum DialogStyles
	{
		StretchHorizontal,
		StretchVertical
	}

//	public class ShowDialogResult
//	{
//		public bool Cancelled { get; private set; }
//		public int ButtonIndex { get; private set; }
//	}

//	public class DialogQuestionResult<TResponse>// where TResponse : class, IQuestionResponse
//	{
//		public IQuestion<TResponse> Question { get; private set; }
//		public TResponse Response { get; private set; }
//		public Exception Error { get; private set; }
//
//		public DialogQuestionResult(TResponse result, IQuestion<TResponse> body, Exception error = null)
//		{
//			Response = result;
//			Question = ArgumentValidator.AssertNotNull(body, "body");
//			Error = error;
//		}
//
////		public bool HasValidResponse
////		{
////			get
////			{
////				return Error == null && Response != null && Response.HasValidAnswer;
////			}
////		}
//	}

//	public interface IQuestion<TResponse>
//	{
//		/* Placeholder. */
//	}
//
//	public interface IQuestionResponse
//	{
//		bool HasValidAnswer { get; }
//	}
}
